package com.serverdemo.application.login;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.serverdemo.application.common.DBOperateTypeEnum;
import com.serverdemo.application.common.DLOperatePlayerDataResponse;
import com.serverdemo.application.common.LDOperatePlayerDataRequest;
import com.serverdemo.application.common.PacketIDConst;
import com.serverdemo.core.entity.SocketEntity;
import com.serverdemo.core.entity.SocketEntityStatusEnum;
import com.serverdemo.core.net.NetPacket;
import com.serverdemo.core.processor.ProcessorManager;
import io.netty.channel.Channel;

/**
 * Created by wangqiang on 2020/4/11.
 */
public class LoginObject
{
    private SocketEntity socketEntity;

    /**
     * 是否已完成登录
     */
    private boolean loginDone = false;

    private String userName;

    private String data;

    public String getData()
    {
        return data;
    }

    public void setData(String data)
    {
        this.data = data;
    }

    public String getUserName()
    {
        return userName;
    }

    public void setUserName(String userName)
    {
        this.userName = userName;
    }

    public SocketEntity getSocketEntity()
    {
        return socketEntity;
    }

    public void setSocketEntity(SocketEntity socketEntity)
    {
        this.socketEntity = socketEntity;
    }

    public SocketEntityStatusEnum getSocketStatus()
    {
        if (socketEntity == null)
        {
            return SocketEntityStatusEnum.EXCEPTION;
        }
        return socketEntity.getStatusEnum();
    }

    public void processInput()
    {
        if (socketEntity == null)
        {
            return;
        }

        for (int i = 0; i < 12; i++)
        {
            NetPacket netPacket = socketEntity.popReceivedPacket();
            if (netPacket == null)
            {
                return;
            }

            dispatchPacket(netPacket);
        }

    }

    public void processOutput()
    {
        if (socketEntity == null)
        {
            return;
        }

        for (int i = 0; i < 100; i++)
        {
            NetPacket netPacket = socketEntity.popSendPacket();
            if (netPacket == null)
            {
                return;
            }

            Channel channel = socketEntity.getChannel();
            if (channel != null)
            {
                channel.writeAndFlush(netPacket);
            }
        }
    }

    public void setLoginDone(boolean loginDone)
    {
        this.loginDone = loginDone;
    }

    public boolean isLoginDone()
    {
        return loginDone;
    }

    public void dispatchPacket(NetPacket netPacket)
    {
        int id = netPacket.getId();
        byte[] body = netPacket.getBody();
        if (body == null)
        {
            return;
        }
        switch (id)
        {
            case PacketIDConst.CS_LOGIN_REQUEST:
            {
                CSLoginRequest request = JSON.parseObject(body, CSLoginRequest.class);
                loginRequest(request);
                break;
            }
            case PacketIDConst.CS_LOGIN_CREATE_ROLE_REQUEST:
            {
                CSCreateRoleRequest request = JSON.parseObject(body, CSCreateRoleRequest.class);
                createRoleRequest(request);
                break;
            }
            case PacketIDConst.CS_LOGIN_SELECT_ROLE_ENTER_REQUEST:
            {
                CSSelectRoleEnterRequest request = JSON.parseObject(body, CSSelectRoleEnterRequest.class);
                selectRoleEnterRequest(request);
                break;
            }
            default:
            {
                break;
            }
        }

    }

    public void loginRequest(CSLoginRequest request)
    {
        if (this.userName != null)
        {
            // 重复发送的错误包
            return;
        }

        this.userName = request.getUserName();

        if (this.userName == null)
        {
            // 空用户名的错误包
            return;
        }

        // -->DB, load玩家数据
        sendDBOperateRequest(request.getUserName(), DBOperateTypeEnum.LOAD_PLAYER_DATA, new LoginLoadPlayerData());
    }

    public void createRoleRequest(CSCreateRoleRequest request)
    {
        if (userName == null)
        {
            return;
        }
        // -->DB, 创建角色
        LoginCreateRoleData roleData = new LoginCreateRoleData();
        roleData.setNickName(request.getNickName());
        roleData.setSex(request.getSex());
        roleData.setUserName(userName);
        sendDBOperateRequest(userName, DBOperateTypeEnum.CREATE_ROLE, roleData);
    }

    public void selectRoleEnterRequest(CSSelectRoleEnterRequest request)
    {
        String userName = request.getUserName();
        if (userName.equals(this.userName))
        {
            // 进入场景
            setLoginDone(true);
        }
    }

    public void sendDBOperateRequest(String userName, DBOperateTypeEnum typeEnum, Object requestData)
    {
        LDOperatePlayerDataRequest dbRequest = new LDOperatePlayerDataRequest();
        dbRequest.setUserName(userName);
        dbRequest.setOperateType(typeEnum);
        dbRequest.setRequestData(requestData);
        ProcessorManager.getInstance().sendMessage(ProcessorManager.getInstance().getDbProcessor(),
                dbRequest);
    }

    public void loadPlayerDataResponse(DLOperatePlayerDataResponse packet)
    {
        SCLoginResponse response = new SCLoginResponse();
        response.setUserName(packet.getUserName());
        String data = packet.getData();
        this.data = data;
        response.setData(data == null ? "" : data);

        sendNetPacket(PacketIDConst.SC_LOGIN_RESPONSE, response);
    }

    public void createRoleResponse(DLOperatePlayerDataResponse packet)
    {
        SCCreateRoleResponse response = new SCCreateRoleResponse();
        response.setResult(packet.getResult());
        this.data = packet.getData();

        sendNetPacket(PacketIDConst.SC_LOGIN_CREATE_ROLE_RESPONSE, response);

        // 直接进入场景
        if (packet.getResult() == 0)
        {
            setLoginDone(true);
        }
    }

    public void sendNetPacket(int packetID, Object packet)
    {
        if (socketEntity == null)
        {
            return;
        }

        byte[] bytes = JSONObject.toJSONBytes(packet);
        NetPacket netPacket = new NetPacket();
        netPacket.setId(packetID);
        netPacket.setBody(bytes);
        netPacket.setLength(bytes.length);

        socketEntity.pushSendPacket(netPacket);
    }
}